package com.jp.refreshlocalcacheclient.net.netty;


import com.jp.refreshlocalcacheclient.net.netty.message.RequestMessage;
import com.jp.refreshlocalcacheclient.net.netty.message.RequestMessageRegistry;
import com.jp.refreshlocalcacheclient.net.netty.thread.DealMessagePoolService;
import com.jp.refreshlocalcacheclient.process.HandleRefreshProcess;
import com.jp.refreshlocalcacheclient.utils.ApplicationContextUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: jipeng
 * @Description:
 * @Date: Created in 2020/5/12 17:10
 */
public class EchoClientHandler extends SimpleChannelInboundHandler<String> {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //向服务器发送所有的缓存key
        registerCacheKey(ctx);

        super.channelActive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("channelId : {}，link error", getChannelId(ctx.channel()));

        cause.printStackTrace();

        ctx.close();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        String strMsg = (String) msg;

        try {
            channelRead0(ctx, strMsg);
        }catch (Exception e){
            logger.error("channelRead error：{}" , e.getMessage());
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String str) throws Exception {
        logger.info("cliend received message : {} " , str);

        //分解消息
        String[] msgs = str.split(",");
        dealMessage(ctx,msgs);
    }

    private int getChannelId(Channel channel){
        return channel.hashCode();
    }

    /**
     * 注册缓存key
     * @param ctx
     */
    private void registerCacheKey(ChannelHandlerContext ctx){
        HandleRefreshProcess handleRefreshProcess =  ApplicationContextUtil.getBean(HandleRefreshProcess.class);
        handleRefreshProcess.registerCacheKey(ctx);
    }


    /**
     * 处理消息
     * @param ctx
     * @param msgs
     */
    private void dealMessage(ChannelHandlerContext ctx,String[] msgs){

        int msgID = Integer.valueOf(msgs[0]);

        RequestMessage rm;
        try {
            //获取消息类型的处理类
            RequestMessageRegistry requestMessageRegistry = ApplicationContextUtil.getBean(RequestMessageRegistry.class);
            rm = requestMessageRegistry.newRequestMessage(msgID);

            //给处理类赋值
            rm.setMsgId(msgID);
            rm.setChannelHandlerContext(ctx);
            rm.setContent(msgs[1]);

            //获取处理队列，把处理类扔到队列中
            DealMessagePoolService pool = ApplicationContextUtil.getBean(DealMessagePoolService.class);
            pool.execut(rm);
        }catch (Exception e){
            logger.error("handle message {} exception, error => {}",msgID, ExceptionUtils.getStackTrace(e));
        }
    }
}
